#include <linux/init.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/kobject.h>


struct kobject *mykobject01;
struct kobject *mykobject02;
struct kset *mykset;
struct kobj_type mytype;




//定义一个回调函数，返回kset的名称
const char *myname(struct kset *kset, struct kobject *kobj)
{
    return "myuevnet_ops->name!!";
}


 //定义一个回调函数，处理kset的uevent事件
int myevent(struct kset *kset, struct kobject *kobj,
            struct kobj_uevent_env *env)
{
    add_uevent_var(env, "MYDEVICE = %s", "RK3588");
    return 0;
}


int myfilter(struct kset *kset, struct kobject *kobj)
{
    if (strcmp(kobj->name, "mykobject01") == 0)
    {
        return 0;   //返回0表示滤除，不上报到用户空间
    }
    else {
        return 1;   //返回1表示 上报
    }


}


struct kset_uevent_ops myuevnet_ops = {
    .name = myname,
    .uevent = myevent,
    .filter = myfilter,
};


static int __init myhotplug_init(void)
{   
    int ret;
   
    // 创建并添加一个kset
    mykset = kset_create_and_add("mykset", &myuevnet_ops, NULL);

    // 分配并初始化kobj
    mykobject01 = kzalloc(sizeof(struct kobject), GFP_KERNEL);
    mykobject01->kset = mykset;
    
    mykobject02 = kzalloc(sizeof(struct kobject), GFP_KERNEL);
    mykobject02->kset = mykset;

    // 添加kobj到kset
    ret = kobject_init_and_add(mykobject01, &mytype, NULL, "%s", "mykobject01");
    ret = kobject_init_and_add(mykobject02, &mytype, NULL, "%s", "mykobject02");

    // 触发一个uevent事件，表示kobject属性发生变化。
    ret = kobject_uevent(mykobject01, KOBJ_ADD);
    ret = kobject_uevent(mykobject02, KOBJ_ADD);

    ret = kobject_uevent(mykobject01, KOBJ_CHANGE);
    // ret = kobject_uevent(mykobject02, KOBJ_ADD);

    printk(KERN_EMERG "myhotplug_init OK!\n");
    return 0;
}

static void __exit myhotplug_exit(void)
{
    // 释放kobj
    kobject_put(mykobject01);
    kobject_put(mykobject02);
    kset_put(mykset);
    printk(KERN_EMERG "myhotplug_exit OK!\n");  
}



module_init(myhotplug_init);
module_exit(myhotplug_exit);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Treasure1029");
